﻿using System;
using BITS.PreCompiler.CSharp.Syntax;

namespace BITS.PreCompiler.CSharp.Visitors.Extensions
{
    public static class SyntaxVisitorExtension
    {
        public static T UnitHandler<T>(this T @this, Action<Unit> visited = null,
           Action<Unit> visiting = null) where T : ISyntaxVisitor<Unit>
        {
            if (visiting != null)
                @this.Visiting = visiting;

            if (visited != null)
                @this.Visited = visited;

            return @this;
        }

        public static T AttributeDeclarationHandler<T>(this T @this, Action<AttributeDeclaration> visited = null,
            Action<AttributeDeclaration> visiting = null) where T : ISyntaxVisitor<AttributeDeclaration>
        {
            if (visiting != null)
                @this.Visiting = visiting;

            if (visited != null)
                @this.Visited = visited;

            return @this;
        }

        public static T ModuleHandler<T>(this T @this, Action<Module> visited = null, Action<Module> visiting = null)
            where T : ISyntaxVisitor<Module>
        {
            if (visiting != null)
                @this.Visiting = visiting;

            if (visited != null)
                @this.Visited = visited;

            return @this;
        }

        public static T UsingHandler<T>(this T @this, Action<Using> visited = null, Action<Using> visiting = null)
            where T : ISyntaxVisitor<Using>
        {
            if (visiting != null)
                @this.Visiting = visiting;

            if (visited != null)
                @this.Visited = visited;

            return @this;
        }

        public static T NamespaceHandler<T>(this T @this, Action<Namespace> visited = null, Action<Namespace> visiting = null)
            where T : ISyntaxVisitor<Namespace>
        {
            if (visiting != null)
                @this.Visiting = visiting;

            if (visited != null)
                @this.Visited = visited;

            return @this;
        }

        public static T InterfaceHandler<T>(this T @this, Action<Interface> visited = null, Action<Interface> visiting = null)
            where T : ISyntaxVisitor<Interface>
        {
            if (visiting != null)
                @this.Visiting = visiting;

            if (visited != null)
                @this.Visited = visited;

            return @this;
        }

        public static T ClassHandler<T>(this T @this, Action<Class> visited = null, Action<Class> visiting = null)
            where T : ISyntaxVisitor<Class>
        {
            if (visiting != null)
                @this.Visiting = visiting;

            if (visited != null)
                @this.Visited = visited;

            return @this;
        }

        public static T StructHandler<T>(this T @this, Action<Struct> visited = null, Action<Struct> visiting = null)
            where T : ISyntaxVisitor<Struct>
        {
            if (visiting != null)
                @this.Visiting = visiting;

            if (visited != null)
                @this.Visited = visited;

            return @this;
        }

        public static T FieldHandler<T>(this T @this, Action<Field> visited = null, Action<Field> visiting = null)
            where T : ISyntaxVisitor<Field>
        {
            if (visiting != null)
                @this.Visiting = visiting;

            if (visited != null)
                @this.Visited = visited;

            return @this;
        }

        public static T PropertyHandler<T>(this T @this, Action<Property> visited = null, Action<Property> visiting = null)
            where T : ISyntaxVisitor<Property>
        {
            if (visiting != null)
                @this.Visiting = visiting;

            if (visited != null)
                @this.Visited = visited;

            return @this;
        }

        public static T PropertyGetHandler<T>(this T @this, Action<Property.Get> visited = null, Action<Property.Get> visiting = null)
            where T : ISyntaxVisitor<Property.Get>
        {
            if (visiting != null)
                @this.Visiting = visiting;

            if (visited != null)
                @this.Visited = visited;

            return @this;
        }

        public static T PropertySetHandler<T>(this T @this, Action<Property.Set> visited = null, Action<Property.Set> visiting = null)
            where T : ISyntaxVisitor<Property.Set>
        {
            if (visiting != null)
                @this.Visiting = visiting;

            if (visited != null)
                @this.Visited = visited;

            return @this;
        }

        public static T MethodHandler<T>(this T @this, Action<Method> visited = null, Action<Method> visiting = null)
            where T : ISyntaxVisitor<Method>
        {
            if (visiting != null)
                @this.Visiting = visiting;

            if (visited != null)
                @this.Visited = visited;

            return @this;
        }
    }
}
